package com.gzdict.common

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import com.alibaba.fastjson.JSON
import com.drake.net.NetConfig
import com.drake.net.interceptor.NetOkHttpInterceptor
import com.drake.net.interceptor.RequestInterceptor
import com.drake.net.interfaces.NetDialogFactory
import com.drake.net.interfaces.NetErrorHandler
import com.drake.net.okhttp.setConverter
import com.drake.net.okhttp.setDebug
import com.drake.net.okhttp.setErrorHandler
import com.drake.net.okhttp.setRequestInterceptor
import com.drake.net.okhttp.setSSLCertificate
import com.drake.net.request.BaseRequest
import com.drake.net.utils.TipUtils.toast
import com.drake.net.utils.isNetworking
import com.drake.statelayout.StateConfig
import com.gzdict.common.exception.NetConvertException
import com.gzdict.common.net.ExceptionEngine
import com.gzdict.common.net.FastJsonConverter
import com.gzdict.common.net.HeaderInterceptor
import com.gzdict.common.ui.NetRequestDialog
import com.gzdict.common.utils.LogUtil.loge
import com.localebro.okhttpprofiler.OkHttpProfilerInterceptor
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.MaterialHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.tencent.mmkv.MMKV
import me.jessyan.autosize.AutoSize
import okhttp3.Interceptor
import java.nio.charset.Charset

/**
 * 描述: 入口初始化配置
 * @author: create by shang
 * date:2024/3/6 0006 13
 */
@SuppressLint("StaticFieldLeak")
object Common {
    lateinit var app: Context
    var debug: Boolean? = true


    /**
     * @param ctx 上下文
     * @param host 服务器地址+端口
     * @param jsonConvert 接口返回数据解析转换  当局部不设置时使用
     * @param requestHeader 轻量请求头处理，例如添加全局cookie
     * @param errorHandler 统一错误码处理，比如 登录信息过期需要重新登录
     * @param netDialog 网络加载对话框
     */
    fun init( ctx: Context,  debug: Boolean? = true ) {
        app = ctx
        this.debug = debug
        AutoSize.initCompatMultiProcess(ctx)
        MMKV.initialize(ctx)
        initStateLayout()
    }

     fun initNet(
        host: String,
        jsonConvert: FastJsonConverter? = FastJsonConverter(),
        headinterceptor: Interceptor? = null,
        errorHandler: ((Map<String, Any>) -> Unit)? = null,
    ) {
        NetConfig.initialize(host, app) {
            if (debug == true) {
                addInterceptor(OkHttpProfilerInterceptor())
                setDebug(true, "CommonTAG")
            } else {
                setDebug(false)
            }
            setConverter(jsonConvert!!)
            setSSLCertificate()
            setErrorHandler(object : NetErrorHandler {
                override fun onError(e: Throwable) {
                    super.onError(e)
                    val errorMap = mutableMapOf<String, Any>()
                    errorMap["message"] = "${e.message}"
                    if (e is NetConvertException){
                        errorMap["code"] = "${e.code}"
                        e.tag?.let { errorMap["data"] = it }
                    }
                    errorHandler?.invoke(errorMap)
                }
            })

            //https 添加请求头
            headinterceptor?.let { addInterceptor(it) }

            //https 非200拦截处理
            errorHandler?.apply {
                val inter = Interceptor {
                    val request = it.request()
                    val response = it.proceed(request)
                    if (response.code in 200..299) {
                        return@Interceptor response
                    }
                    val source = response.body?.source()
                    source?.request(Long.MAX_VALUE)
                    val buffer = source?.buffer
                    val contentType = response.body?.contentType()
                    var charset = Charset.forName("UTF-8")
                    charset = contentType?.charset(charset)
                    val result = buffer?.clone()?.readString(charset)

                    val map = JSON.parse(result) as Map<String, Any>
                    this.invoke(map)

                    it.proceed(request)
                }
                addInterceptor(inter)
            }
        }
        NetConfig.dialogFactory = NetDialogFactory { activity -> NetRequestDialog(context = activity) }
    }

    private fun initStateLayout() {
        SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, _ ->
            MaterialHeader(context)
        }
        SmartRefreshLayout.setDefaultRefreshFooterCreator { context, _ ->
            ClassicsFooter(context)
        }
        StateConfig.apply {
            loadingLayout = R.layout.layout_loading
            emptyLayout = R.layout.layout_empty
            errorLayout = R.layout.layout_error
        }
    }
}

